<?php
/**
 * 支付接口
 * @date    2021-01-01
 * @author  kiro
 * @email   294843009@qq.com
 * @version 1.0
 */
namespace App\Http\Controllers\Api\V1;

use App\Models\Config;
use App\Models\User;
use App\Models\UserVipLog;
use App\Models\UserVipShop;
use App\Services\PayService;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PayController extends ApiController
{
    private $apiUrl = 'http://154.204.39.2';

    // 支付发起
    public function do(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error("请先登录", null, 500);
        }
        $config = Config::getConfig('pay');

        $accesskey = $config['pay_accesskey'] ?:'';
        $secretkey = $config['pay_secretkey'] ?:'';
        $return_url = $config['pay_return_url'] ?:'';
        $callback_url = $config['pay_callback_url'] ?:'';

        $type = $request->get('type');
        $pay_type = $request->get('pay_type') ?:'AMOUNT';
        $amount = $request->get('amount');
        if (empty($type)) {
            return $this->error("支付方式不能为空");
        }
        if (empty($amount)) {
            return $this->error("金额不能为空");
        }

        $pay_order_id = date('YmdHis').mt_rand(1000,9999);

        $data = array(
    		"pid" => $accesskey,//商户ID
    		"out_trade_no"	=> $pay_order_id,//商户订单号
    		"type" => $type,//支付方式
    		"name"	=> "支付",//商品名称
    		"money"	=> $amount,//付款金额
    		"param"	=> "",//自定义参数
    		"notify_url" => $callback_url,//异步通知地址
    		"return_url" => $return_url//同步跳转地址
        );

        ksort($data); //重新排序$data数组
        reset($data); //内部指针指向数组中的第一个元素
        $sign = ''; //初始化需要签名的字符为空
        $urls = ''; //初始化URL参数为空
        foreach ($data AS $key => $val) { //遍历需要传递的参数
            if ($val == ''||$key == 'sign'||$key == 'param') continue; //跳过这些不参数签名
            if ($sign != '') { //后面追加&拼接URL
                $sign .= "&";
                $urls .= "&";
            }
            $sign .= "$key=$val"; //拼接为url参数形式
            $urls .= "$key=" . urlencode($val); //拼接为url参数形式并URL编码参数值
        }
        $query = $urls . '&sign=' . md5($sign . $secretkey); //创建订单所需的参数
        $url = $this->apiUrl."/submit.php?{$query}"; //支付页面

        PayService::do($this->getUserId(), $amount, $type, $pay_order_id, $pay_type);
        return $this->success('成功', ['url' => $url]);
    }

    // 回调
    public function return(Request $request)
    {
        $config = Config::getConfig('pay');

        $secretkey = $config['pay_secretkey'] ?:'';

        $api = $_REQUEST;
        ksort($api);
        reset($api);

        $sign = '';

        foreach ($api AS $key => $val) { //遍历GET和POST参数
            if ($val == '' || $key == 'sign' || $key == 'sign_type' || $key == 'param') continue; //跳过这些不签名
            if ($sign) $sign .= '&'; //第一个字符串签名不加& 其他加&连接起来参数
            $sign .= "$key=$val"; //拼接为url参数形式
        }

        if (md5($sign . $secretkey)==$api['sign']) { //不合法的数据

            //请在这里加上商户的业务逻辑程序代

            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

            $out_trade_no = $api['out_trade_no'];//商户订单号

            $type = $api['type'];//支付方式

            PayService::back($type, $out_trade_no);

            exit("success");//请不要修改或删除

        } else {

            exit("失败失败");//验证失败

        }
    }

    // 回调
    public function notify(Request $request)
    {
        $config = Config::getConfig('pay');

        $secretkey = $config['pay_secretkey'] ?:'';

        $api = $_REQUEST;
        ksort($api);
        reset($api);

        $sign = '';

        foreach ($api AS $key => $val) { //遍历GET和POST参数
            if ($val == '' || $key == 'sign' || $key == 'sign_type' || $key == 'param') continue; //跳过这些不签名
            if ($sign) $sign .= '&'; //第一个字符串签名不加& 其他加&连接起来参数
            $sign .= "$key=$val"; //拼接为url参数形式
        }
        
        cache(['api' => $api, 'sign' => md5($sign . $secretkey)], 300000);
        

        if (md5($sign . $secretkey)==$api['sign']) { //不合法的数据

            //请在这里加上商户的业务逻辑程序代

            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

            $out_trade_no = $api['out_trade_no'];//商户订单号

            $type = $api['type'];//支付方式

            PayService::back($type, $out_trade_no);

            exit("success");//请不要修改或删除

        } else {

            exit("失败失败");//验证失败

        }
    }

    // 支付发起
    public function doVip(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error("请先登录", null, 500);
        }
        $mode = $request->get('mode');
        $pay_type = $request->get('pay_type');
        $amount = $request->get('amount');
        if (empty($amount)) {
            return $this->error("金额不能为空");
        }
        PayService::doVip($this->getUserId(), $amount, $pay_type, 0);
        return $this->success('成功', []);
    }

    // 回调
    public function notifyVip(Request $request)
    {
        $pay_type = $request->get('pay_type');
        $pay_order_id = 0;
        PayService::backVip($pay_type, $pay_order_id);
        return $this->success('成功', []);
    }

    //直接开通vip
    public function vip(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error("请先登录", null, 500);
        }
        $pay_type = $request->get('pay_type', 'AMOUNT');
        $shop_id = $request->get('shop_id');
        if (empty($shop_id)) {
            return $this->error("shop_id不能为空");
        }
        $info = UserVipShop::where('id', $shop_id)->where('status', 1)->first();
        if ($info->type == 1) {

            DB::beginTransaction();
            UserService::doAccount($this->getUserId(), -$info->price, '余额支付', $pay_type, 'PAYMENT');

            $logId = UserVipLog::add($this->getUserId(), $shop_id, $info->price, 3, 0);
            try {
                $month = UserVipShop::where('id', $shop_id)->value('month');
                $vip_end_time = User::where('id', $this->getUserId())->value('vip_end_time');
                if (empty($month)) {
                    throw new \Exception("商品信息有问题");
                }

                if ($vip_end_time > strtotime(date('Y-m-d'))) {
                    $vip_end_time_new = strtotime("+{$month} month", $vip_end_time);
                } else {
                    $vip_end_time_new = strtotime("+{$month} month", strtotime(date('Y-m-d')));
                }
                $result = User::where('id', $this->getUserId())->update(['vip_end_time' => $vip_end_time_new]);
                if (!$result) {
                    throw new \Exception("更新过期时间失败");
                }
                UserVipLog::where('id', $logId)->update(['status' => 2]);
                DB::commit();
                return $this->success('成功', []);
            } catch (\Exception $e) {
                DB::rollBack();
                return $this->error($e->getMessage());
            }
        } else {
            return $this->error("暂不支持");
        }
    }
}
